{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# [1、PyTorch介绍与张量的创建](https://www.bilibili.com/video/BV1ov411M7xL?spm_id_from=333.788.videopod.sections&vd_source=cdd897fffb54b70b076681c3c4e4d45d)\n",
    "[Tensor](https://docs.pytorch.org/tutorials/beginner/basics/tensorqs_tutorial.html) 是多维数组，矩阵是二维\n",
    "pytorch使用Tensor来对模型处理、计算\n",
    "Tensor和numpy数组很像，但张量可以在GPU中运行，此外张量和np数组可以共享同一块内存，只要你是原地操作。\n",
    "张量支持自动微分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 创建张量的方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 从源数据中创建"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(<class 'list'>, <class 'torch.Tensor'>, torch.float32)\n",
      "tensor([[1., 2.],\n",
      "        [3., 4.]])\n"
     ]
    }
   ],
   "source": [
    "# 1. 直接从 数组创建\n",
    "data = [[1,2], [3,4]]\n",
    "x = torch.Tensor(data)\n",
    "print(f\"{type(data), type(x), x.dtype}\")\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2]\n",
      " [3 4]]\n",
      "tensor([[1, 2],\n",
      "        [3, 4]])\n",
      "[[-1  2]\n",
      " [ 3  4]]\n",
      "tensor([[-1,  2],\n",
      "        [ 3,  4]])\n"
     ]
    }
   ],
   "source": [
    "np_data = np.array(data)\n",
    "# 使用 torch.from_numpy()：共享内存。\n",
    "# 使用 torch.tensor()：不共享内存（会创建副本）。\n",
    "# 使用 torch.as_tensor()：可能共享内存，如果dtype和设备兼容且NumPy数组是连续的，则共享；否则会创建副本。\n",
    "\n",
    "x = torch.from_numpy(np_data)\n",
    "# y = torch.from_numpy(np_data)\n",
    "print(f\"{np_data}\\n{x}\")\n",
    "# 现在修改 np 中的元素，看看x是否一样\n",
    "np_data[0,0] *= -1\n",
    "print(f\"{np_data}\\n{x}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 指定分布"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[0., 0., 0.],\n",
      "        [0., 0., 0.]])\n",
      "tensor([[1., 1., 1.],\n",
      "        [1., 1., 1.]])\n",
      "tensor([[0.9267, 0.6991, 0.3671],\n",
      "        [0.1024, 0.4135, 0.1172]])\n",
      "tensor([[5.5216e-05, 0.0000e+00, 0.0000e+00],\n",
      "        [0.0000e+00, 0.0000e+00, 1.4580e-19]])\n"
     ]
    }
   ],
   "source": [
    "x = torch.zeros((2,3))\n",
    "print(x)\n",
    "x = torch.ones(x.shape)\n",
    "print(x)\n",
    "x = torch.rand_like(x)\n",
    "print(x)\n",
    "x = torch.empty(x.shape) # 不初始化数据\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0.0000, 0.1000, 0.2000, 0.3000, 0.4000, 0.5000, 0.6000, 0.7000, 0.8000,\n",
       "        0.9000, 1.0000])"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.linspace(start=0, end=1, steps=11) # 一共11个，线性均匀分布\n",
    "# 包含头尾"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([  1.,  10., 100.])"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.logspace(start=0, end=2, steps=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1., 0., 0.],\n",
       "        [0., 1., 0.],\n",
       "        [0., 0., 1.]])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 对角线全为1\n",
    "torch.eye(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# arange 不包含end\n",
    "torch.arange(start=0, end=10, step=1)\n",
    "# range过时了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0, 0],\n",
       "        [0, 0]])"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.full((2,2), fill_value=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tensor 基本操作"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 判断"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "是不是张量： True False\n",
      "是不是非零： True False\n",
      "是不是非零： False True\n"
     ]
    }
   ],
   "source": [
    "# torch.is_tensor 是不是张量\n",
    "x = torch.empty(2,3)\n",
    "y = np.empty_like(x)\n",
    "print(\"是不是张量：\", torch.is_tensor(x), torch.is_tensor(y))\n",
    "\n",
    "x = torch.Tensor([1])\n",
    "y = torch.Tensor([False])\n",
    "print(\"是不是非零：\", torch.is_nonzero(x), torch.is_nonzero(y))\n",
    "\n",
    "\n",
    "x = torch.Tensor([1,2,3])\n",
    "y = torch.complex(torch.zeros(1,2), torch.ones(1,2))\n",
    "print(\"是不是非零：\", torch.is_complex(x), torch.is_complex(y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 存储"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cpu\n",
      "cuda:0\n"
     ]
    }
   ],
   "source": [
    "x = torch.empty((2,3))\n",
    "print(x.device)\n",
    "if torch.cuda.is_available():\n",
    "    x = x.to('cuda')\n",
    "    print(x.device)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[1., 1.],\n",
      "        [1., 1.],\n",
      "        [2., 2.],\n",
      "        [2., 2.]])\n",
      "tensor([[1., 1., 2., 2.],\n",
      "        [1., 1., 2., 2.]])\n"
     ]
    }
   ],
   "source": [
    "# cat操作\n",
    "a = torch.ones((2,2))\n",
    "b = torch.ones((2,2)) * 2\n",
    "print(torch.cat([a,b], dim=0)) # 对行扩充 --> 4 行\n",
    "print(torch.cat([a,b], dim=1)) # 对列扩充 --> 4 列"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 计算\n",
    "\n",
    "见：[2、PyTorch张量的运算API（上）](2、PyTorch张量的运算API（上）.ipynb)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1.],\n",
       "        [1.]])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.ones((2,1))\n",
    "x"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "dl",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
